package io.github.biezhi.wechat.api;

import io.github.biezhi.wechat.WeChatBot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author sunjisong 2019-07-30
 */
public class KeepAliveTask implements Runnable {

    private static final Logger log = LoggerFactory.getLogger(KeepAliveTask.class);

    private Long periodStart = 60 * 30 * 1000L; //半小时

    private Long periodEnd = 60 * 60 * 1000L; //一小时

//    private Long periodStart = 30 * 1000L; //半小时
//
//    private Long periodEnd = 60 * 1000L; //一小时


    private WeChatBot bot;

    private WeChatApi api;

    final DelayQueue delayQueue = new DelayQueue();

    public KeepAliveTask(WeChatBot bot){
        this.bot = bot;
        this.api = bot.api();
        addDelay();
    }

    @Override
    public void run() {
        while (true){
            if(!bot.isRunning()){
                try {
                    log.info("keepAliveTask sleep 1 minutes");
                    TimeUnit.MINUTES.sleep(1);
                } catch (InterruptedException e) {}
                continue;
            }
            try {
                KeepAliveLoop task = (KeepAliveLoop) delayQueue.take();
                if(null != task){
                    log.info("{},send 文件传输助手 ， msg: ''",task.getTriggerTimeMills());
                    bot.sendMsgByName("文件传输助手","");
                }
                addDelay();
            } catch (InterruptedException e) {
                log.error("keepAlive failed : {}",e);
            }
        }
    }


    private void addDelay(){
        long period = nextLong(periodEnd) + periodStart;
        delayQueue.offer(new KeepAliveLoop(System.currentTimeMillis() + period));
    }

    private Long nextLong(long n) {
        // error checking and 2^x checking removed for simplicity.
        long bits, val;
        do {
            bits = (new Random().nextLong() << 1) >>> 1;
            val = bits % n;
        } while (bits-val+(n-1) < 0L);
        return val;
    }
}
